#ifndef __MMMConverterGUI_WINDOW_H_
#define __MMMConverterGUI_WINDOW_H_

#include "ui_MMMConverterGUI.h"

#include <VirtualRobot/VirtualRobotCommon.h>
#include <VirtualRobot/Nodes/Sensor.h>
#include <string>
#include <Inventor/sensors/SoSensor.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>

#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>

#include <MMM/MMMCore.h>
#include <MMMSimoxTools/RobotPoseDifferentialIK.h>
#include <MMM/Motion/Legacy/LegacyMotionReaderC3D.h>

// workaround for qt moc, causing problems with boost under visual studio
#ifndef Q_MOC_RUN
#include <MMM/Motion/Legacy/Converter/ConverterFactory.h>
#include <MMM/Motion/Legacy/Converter/MarkerBasedConverter.h>
#include <MMM/Model/ModelProcessorFactory.h>
#include <MMM/Motion/Legacy/LegacyMotionReaderXML.h>
#include <MMM/Motion/Legacy/LegacyMotion.h>
#endif


//qtable
#include <QStandardItem>
#include <QListWidgetItem>
#include <qgl.h>



class MMMConverterGUIWindow : public QMainWindow
{
	Q_OBJECT
public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW

        MMMConverterGUIWindow(	const std::string &dataFileSource,
                                const std::string &modelFileSource,
                                const std::string &modelFileTarget,
                                const std::string &modelProcessorNameSource,
                                const std::string &modelProcessorNameTarget,
                                const std::string &modelProcessorConfigFileSource,
                                const std::string &modelProcessorConfigFileTarget,
                                const std::string &converterName,
                                const std::string &converterFile,
                                const std::string &markerprefix);

	~MMMConverterGUIWindow();

    /*!< Executes the SoQt mainLoop. You need to call modelFilethis in order to execute the application. */
	int main();

public slots:

	void quit();
	void redraw();
	void closeEvent(QCloseEvent *event);
	void sliderMoved(int pos);
	void spinnerMoved();
	void updateVisu();

protected:
    void progress();
    void loadModelFiles();
	void buildMarkerVisu();
	void updateMarkerVisu();
	void buildModelMarkerVisu();
	void updateModelMarkerVisu();
	void updateDistanceVisu();
    void updateJacobianVisu();

	void setupModelProcessor();
	void setupConverter();
	void setupUI();
    void initializeRobotVisu(MMM::ModelPtr model);
    void initializeConverter(MMM::ModelPtr sourceModel, MMM::AbstractMotionPtr motion, MMM::ModelPtr targetModel);
	void loadData();
	
	//qtable stuff
	void setupTable();
    void setupDoFTable();
    void updateTables();

	void jumpToFrame(int pos);

	void createMotionVisu(VirtualRobot::TrajectoryPtr tr, SoSeparator* addToThisSep);

    static void timerCB(void * data, SoSensor * sensor);

	// filenames
    /*
	std::string modelFile;
    std::string viconFile;
	std::string modelProcessorType;
	std::string modelProcessorFile;
	std::string converterName;
    std::string converterFile;*/
    std::string dataFileSource;
    std::string converterName;
    std::string converterConfigFile;
    std::string modelFileSource;
    std::string modelProcessorNameSource;
    std::string modelProcessorConfigFileSource;
    std::string modelFileTarget;
    std::string modelProcessorNameTarget;
    std::string modelProcessorConfigFileTarget;
    std::string markerPrefix;

    // organizing timer
    SoSensorManager* _pSensorMgr;
    SoTimerSensor* _pSensorTimer;
    bool timerSensorAdded;

	// Motion and Poses
    MMM::LegacyMotionPtr resultModelMotion;
    MMM::LegacyMotionPtr modelMotionSource;
    MMM::MarkerMotionPtr markerMotion;
    MMM::ModelProcessorFactoryPtr modelFactorySource;
    MMM::ModelProcessorFactoryPtr modelFactoryTarget;
    MMM::ModelProcessorPtr modelProcessorSource;
    MMM::ModelProcessorPtr modelProcessorTarget;
	MMM::ConverterFactoryPtr converterFactory;
	MMM::MarkerBasedConverterPtr converter;
    MMM::ModelPtr modelScaledTarget;
    MMM::ModelPtr modelTarget;
    MMM::ModelPtr modelScaledSource;
    MMM::ModelPtr modelSource;
    bool bMotionIsVicon;

	//VirtualRobot::TrajectoryPtr trajectory;
	VirtualRobot::RobotNodeSetPtr rns;
    VirtualRobot::RobotNodeSetPtr rns_prismatic;

	// Robot Pointer and Seperator Nodes
	VirtualRobot::RobotPtr robot;
	SoSeparator *sceneSep;
	SoSeparator *robotSep;
	SoSeparator *motionSep;
	SoSeparator *rootCoordSep;
	SoSeparator *floorSep;
    SoSeparator *markerSep;
    SoSeparator *markerTextSep;
	SoSeparator *modelMarkerSep;
	SoSeparator *modelMarkerTextSep;
	SoSeparator *distVisuSep;
    SoSeparator *jacDistance;
    SoSeparator *jacDirection;

	SoSwitch *swFloor;

	// UI Class and Viewer
	Ui::MainWindowMMMConverterGUI UI;
	SoQtExaminerViewer *viewer;


    float scale; //should be height eventually
    size_t selectedMarker;
	size_t selectedModelMarker;
    size_t selectedDoF;
	size_t currentFrame;
    int _framePosition;

	std::map<std::string, std::string> markerMapping;
	std::map<std::string, VirtualRobot::SensorPtr> modelMarkers;
    void updateSlider(int pos);

	void saveScreenshot();

	VirtualRobot::VisualizationFactory::Color colorViconMarker;
	VirtualRobot::VisualizationFactory::Color colorViconMarkerSelected;
	VirtualRobot::VisualizationFactory::Color colorModelMarker;
	VirtualRobot::VisualizationFactory::Color colorModelMarkerSelected;

private slots:
	void markerSelected(int index);
	void modelMarkerSelected(int index);
    void dofSelected(int index);
	void saveMotion();
    void playMotion();

    void buttonInitClicked();
	void buttonStepClicked();
	void buttonCompleteClicked();
    void button40FramesClicked();
	void buttonSaveClicked();


};

#endif 
